package net.lummox.command;

import java.util.ArrayList;
import java.util.List;

import net.lummox.common.RequestedAction;
import net.lummox.common.TurnAction;
import net.lummox.common.util.RandomGen;
import net.lummox.model.Turn;

public class CommandSayLetter extends CommandImpl {

	@Override
	public Turn execute(Turn turn) {
		List<String> words = aiDao.getWordsLike(turn.getOpponentPartOfWord());
		if (words.size() == 0) {
			turn.setAction(TurnAction.ASK_WORD);
			turn.setPartOfWord("");
		} else {
			int wordIndex = RandomGen.getInt(words.size());
			String word = words.get(wordIndex);

			if (turn.getOpponentPartOfWord().length() == 0) {
				chooseRandomLetterFromWord(turn, word);
			} else {
				chooseLetterFromWord(turn, word);
			}
			turn.setAction(TurnAction.LETTER_ADDED);
		}

		return turn;
	}

	private void chooseRandomLetterFromWord(Turn turn, String word) {
		int charIndex = RandomGen.getInt(word.length());

		String answer = "" + word.charAt(charIndex);

		turn.setPartOfWord(answer);
	}

	private void chooseLetterFromWord(Turn turn, String word) {
		List<PossibleAdding> list = getPossibleAddingsList(word,
		        turn.getOpponentPartOfWord());

		int recordIndex = RandomGen.getInt(list.size());
		PossibleAdding record = list.get(recordIndex);
		if (record.isLeft()) {
			turn.setPartOfWord(record.getSymbol() + turn.getOpponentPartOfWord());
		} else {
			turn.setPartOfWord(turn.getOpponentPartOfWord() + record.getSymbol());
		}
	}

	private List<PossibleAdding> getPossibleAddingsList(String word,
	        String inputPhrase) {
		List<PossibleAdding> list = new ArrayList<PossibleAdding>();
		StringBuilder sb = new StringBuilder(word);
		int startIndex = 0;
		int located = sb.indexOf(inputPhrase, startIndex);
		while (located != -1) {
			if (located - 1 >= 0) {
				PossibleAdding record = new PossibleAdding();
				record.setSymbol(sb.charAt(located - 1));
				record.setLeft(true);
				list.add(record);
			}
			if (located + inputPhrase.length() < sb.length()) {
				PossibleAdding record = new PossibleAdding();
				record.setSymbol(sb.charAt(located + inputPhrase.length()));
				record.setLeft(false);
				list.add(record);
			}
			startIndex = located + inputPhrase.length();
			located = sb.indexOf(inputPhrase, startIndex);
		}
		return list;
	}

	private class PossibleAdding {
		private char symbol;
		private boolean left;

		public void setSymbol(char symbol) {
			this.symbol = symbol;
		}

		public char getSymbol() {
			return this.symbol;
		}

		public void setLeft(boolean left) {
			this.left = left;
		}

		public boolean isLeft() {
			return this.left;
		}
	}

	@Override
	public String getName() {
		return RequestedAction.SAY_LETTER.name();
	}
}
